package codificacaojava;

import java.io.*;
import java.util.*;
import javax.swing.JFileChooser;
import org.biojava.bio.*;
import org.biojava.bio.seq.*;
import org.biojava.bio.seq.io.*;
import org.biojava.bio.Annotation;
import org.biojavax.bio.seq.*;

// ===============================================================================
/**
 * A classe LerFasta lê um arquivo *.fasta que contém as seqüências de nucleotídeos (atcg...)
 * e gera para cadas seqüência um arquivo *.seq com a "tradução" das representações <atcg...>
 * em <adenine thymine citosine guanine...>.
 * nome_arquivo.fasta ==> nome_arquivo.seq
 * @author Susan Higashi
 */
// ===============================================================================
public class LerFasta
{
        private List lista = new LinkedList();
	/**
	 * Arquivo de entrada em formato FASTA.
	 */
	private File arquivo; 
	/**
	 * Diretório de destino dos arquivo .seq.
	 */
	private File dirDestino;
        
        /**
         * Seqüência de nucleotídeos (A, T, C, G).
         */
        private String sequencia[];
        /**
         * Anotacoes da sequencia de nucleotideos.
         */        
        Annotation a;

        // -----------------------------------------------------------------------------------------        
        /**
         * Seta o atributo sequencia com uma seqüência passada por parâmetro (seq[]).
         * @param seq Seqüência de nucleotídeos.
         */
        public void setSequencia(String seq[]){ sequencia = seq; }
        // -----------------------------------------------------------------------------------------        
        /**
         * Retorna a seqüência de nucleotídeos.
         * @return retorna a seqüência.
         */
        public String[] getSequencia(){ return sequencia; }
        // -----------------------------------------------------------------------------------------        
        /**
         * Seta o atributo a com uma anotacao passada por parâmetro (seq[]).
         * @param z anotacao sobre referente a sequencia de nucleotideos.
         */
        public void setAnnotation(Annotation z) { a = z; }
        // -----------------------------------------------------------------------------------------        
        /**
         * Retorna a anotacao referente a sequencia de nucleotideos.
         * @return retorna a anotacao.
         */        
        public Annotation getAnnotation() { return a; }
        // -----------------------------------------------------------------------------------------
	/**
	 * Seleciona o arquivo de entrada com a(s) seqüência(s) de nucleotídeos
         * e o diretório de destino dos arquivos .seq (contém a seqüência de nucleotídeos).
	 *
	 */         
	public void definirArquivos()
        {
            //SELECAO DO ARQUIVO DE ENTRADA (.FASTA)
            JFileChooser arqSel = new JFileChooser(System.getProperties().getProperty("user.dir"));
            arqSel.setFileSelectionMode(JFileChooser.FILES_ONLY);
            arqSel.setDialogTitle("Selecione o arquivo que contém as seqüências (*.fasta)");

            int result = arqSel.showOpenDialog(arqSel);

            // caso o usuario clique no botao "Cancel"
            if (result==JFileChooser.CANCEL_OPTION) System.exit(1);

            // recebe o arquivo selecionado
            arquivo = arqSel.getSelectedFile();

            //SELECAO DO DIRETORIO DE DESTINO
            JFileChooser destSel = new JFileChooser(System.getProperties().getProperty("user.dir"));
            destSel.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            destSel.setDialogTitle("Selecione o diretório destino dos arquivos de seqüência");

            int resultDir = destSel.showOpenDialog(destSel);

            if (resultDir==JFileChooser.CANCEL_OPTION) System.exit(1);	// caso o usuario clique no botao "Cancel"

            dirDestino = destSel.getSelectedFile();			// recebe o diretorio de destino
	}
        // -----------------------------------------------------------------------------------------
	/**
	 * Utiliza a classe biojava para ler um arquivo no formato FASTA. Invoca demais 
	 * métodos necessários para realizar o processamento.
	 */
	public void lerArquivo()
        { 
            // inicio e fim da identificacao da proteina
            //int idInicio = 3, idFim = 11;
            // inicio da anotacao "util" = genero especie

            try 
            {
                BufferedReader arqFasta = new BufferedReader(new FileReader(arquivo));//arquivo Fasta
                SequenceIterator seqIt = SeqIOTools.readFastaDNA(arqFasta);           //le o arquivo fasta com as sequencias
                    
                //Realiza as operacoes para todas as cadeias.
                while (seqIt.hasNext()) 
                {
                    Sequence seq = seqIt.nextSequence();
                    
                    String sequencia[] = new String[seq.length()];

                    //????
                    for (int i = 0; i <  seq.length(); i++) 
                    {
                        sequencia[i] = seq.symbolAt(i+1).getName();
                    }             
                    
                    setSequencia(sequencia);

                    /*a = seq.getAnnotation();        // pega a anotacao contina no arquivo fasta
                    String anotacao = a.toString(); // passa a anotacao para o formato String
                    
                    int idInicioAnno = 45;                   // indice de inicio da string que contem o nome da bacteria
                    int idFimAnno = anotacao.indexOf("16S"); // indice de fim da string que contem o nome da bacteria
                    
                    String nomeBac = anotacao.substring(idInicioAnno,idFimAnno); // nome da bacteria (Genero especie id_bacteria)
                                        
                    // gambis soh pra corrigir os nomes q estao assim: | Pseudomonas sp.
                    if (nomeBac.startsWith("| ") == true)
                    {
                        idInicioAnno = 2;
                        nomeBac = nomeBac.substring(idInicioAnno);
                    }*/
                    
                    int idIncio = 3;
                    int idFim = seq.getName().substring(idIncio).indexOf("|gb");//12
                    if (idFim == -1)
                    {
                        idFim = seq.getName().substring(idIncio).indexOf("|");  //12
                    }
                    
                    String nomeSeq = "gi_";
                    nomeSeq = nomeSeq.concat(seq.getName().substring(idIncio, idIncio+idFim));
                  
                    lista.add(nomeSeq);
                                     
                    try { gravarArquivo(getSequencia(), nomeSeq, dirDestino.getPath()); }
                    catch (IOException e) { e.printStackTrace(); }
                }
                
            } 
            catch (BioException ex) { ex.printStackTrace(); }               //not in fasta format or wrong alphabet
            catch (NoSuchElementException ex) { ex.printStackTrace(); }     //no fasta sequences in the file
            catch (FileNotFoundException ex) { ex.printStackTrace(); }      //problem reading file
        }           
        // -----------------------------------------------------------------------------------------
        public void comparaSeq() throws IOException
        {
            BufferedWriter arqW = null;
            File arq = null;
            arq = new File("entradas_repetidas.txt");
            arqW = new BufferedWriter(new FileWriter(arq));
            
            if (arq.exists()) arq.delete();
            
            for (int i=0; i < lista.size(); i++)
            {   
                for (int j=0; j < lista.size(); j++)
                {
                    if(i == j)
                    {
                        break;
                    }
                    
                    if (lista.get(i).equals(lista.get(j)))
                    {
                        arqW.write(lista.get(i).toString().substring(3)+"\n");
                        arqW.flush();
                    }
                }
            }
            arqW.close();
        }
        // -----------------------------------------------------------------------------------------        
	/**
	 * Grava uma seqüência de nucleotídeos em um arquivo .seq.
 	 * @param s[] seqüência de nucleotídeos.
	 * @param nomeSeq nome da seqüência. Neste caso é o ?????????código de identificação 
	 * da proteína.
         * @param destino diretório de destino das seqüênias (arquivos .seq)
	 */
	private void gravarArquivo(String s[], String nomeSeq, String destino) throws IOException 
        {	
            Utilitario  os = new Utilitario();
            String so = os.getSO();

            String seq[];

            BufferedWriter arqE = null;
            File arquivo = null;

            //cria novo arquivo .seq
            if (so.equals("windows")) arquivo = new File (destino + "\\" +nomeSeq+".seq");
            else arquivo = new File (destino + "/" +nomeSeq+".seq");

            if (arquivo.exists()) arquivo.delete();		//se o arquivo ja existir apaga-o e cria-o novamente (sobreescreve)

            arqE = new BufferedWriter(new FileWriter(arquivo));	//arqE = Arquivo de escrita
            
            for (int j=0; j < getSequencia().length; j++)
            {
                arqE.write(getSequencia()[j] + " ");
                arqE.flush();
            }
            
            arqE.close();
	}     
}
